package io2.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;

public class AIOServer {
    public static void main(String[] args) throws IOException {
        AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(8080));
        serverSocketChannel.accept(serverSocketChannel, new CompletionHandler<AsynchronousSocketChannel, AsynchronousServerSocketChannel>() {
            @Override
            public void completed(AsynchronousSocketChannel result, AsynchronousServerSocketChannel attachment) {
                try {
                    System.out.println("接收到新连接 -> " + result.getRemoteAddress().toString());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                // 读数据
                result.read(buffer, buffer, new ReadCompletionHandler(result));
                // 继续接收新连接
                attachment.accept(attachment, this);
            }

            @Override
            public void failed(Throwable exc, AsynchronousServerSocketChannel attachment) {
                System.out.println("接收连接出错");
                exc.printStackTrace();
            }
        });
        System.out.println("服务启动成功");
        System.in.read();
    }

    /**
     * 读取完成处理器
     */
    private static class ReadCompletionHandler implements CompletionHandler<Integer, ByteBuffer> {

        private AsynchronousSocketChannel socketChannel;

        public ReadCompletionHandler(AsynchronousSocketChannel socketChannel) {
            this.socketChannel = socketChannel;
        }

        @Override
        public void completed(Integer result, ByteBuffer attachment) {
            System.out.println("result -> " + result);
            attachment.flip();
            // 读取数据
            byte[] bytes = new byte[attachment.remaining()];
            attachment.get(bytes);
            String request = new String(bytes);
            System.out.println("收到数据 —> " + request);

            // 返回数据
            ByteBuffer buffer = ByteBuffer.wrap(String.valueOf(System.currentTimeMillis()).getBytes());
            socketChannel.write(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
                @Override
                public void completed(Integer result, ByteBuffer attachment) {
                    if(attachment.hasRemaining()) {
                        socketChannel.write(attachment, attachment, this);
                    } else {
                        System.out.println("发送完成");
                    }
                }

                @Override
                public void failed(Throwable exc, ByteBuffer attachment) {
                    System.out.println("发送失败");
                    exc.printStackTrace();
                }
            });
        }

        @Override
        public void failed(Throwable exc, ByteBuffer attachment) {
            System.out.println("读取数据出错");
            exc.printStackTrace();
            try {
                socketChannel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
